import 'dart:async';

import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
import 'package:xws/helpers/safe_state.dart';
import 'package:xws/helpers/safe_value_notifier.dart';
import 'package:xws/utils/app_util.dart';
import 'package:xws/utils/log_util.dart';
import 'package:xws/utils/theme_util.dart';
import 'package:xws/widgets/app_btn.dart';
import 'package:xws/widgets/ex_value_builder.dart';

///  录音状态
enum _PlayStatus { pause, playing }

/// 播放录音
class PlayRecord extends StatefulWidget {
  const PlayRecord({
    Key? key,
    required this.url,
  }) : super(key: key);

  @override
  _PlayRecordState createState() => _PlayRecordState();

  final String url;
}

class _PlayRecordState extends State<PlayRecord> with SafeState<PlayRecord> {
  late SafeValueNotifier<double> _playIndicator;
  late AudioPlayer _audioPlayer;
  Duration? _duration;

  _PlayStatus _status = _PlayStatus.pause;

  StreamSubscription<Duration>? _durationStream;
  StreamSubscription<void>? _complateStream;
  StreamSubscription<Duration>? _playStream;

  @override
  void initState() {
    super.initState();
    _playIndicator = SafeValueNotifier<double>(0);
    _init();
  }

  @override
  void dispose() {
    _playIndicator.dispose();
    _audioPlayer.dispose();
    _cancelStream();
    super.dispose();
  }

  Future<void> _init() async {
    _audioPlayer = AudioPlayer();
  }

  void _cancelStream() {
    _durationStream?.cancel();
    _durationStream = null;
    _complateStream?.cancel();
    _complateStream = null;
    _playStream?.cancel();
    _playStream = null;
  }

  /// 开始播放
  Future<void> _play() async {
    try {
      debug('play:${widget.url}');

      await _audioPlayer.play(widget.url, isLocal: false);

      _complateStream ??= _audioPlayer.onPlayerCompletion.listen((_) async {
        await _pause();
        _playIndicator.value = 0;
      });

      _durationStream ??= _audioPlayer.onDurationChanged.listen((Duration d) {
        _duration = d;
      });

      _playStream ??= _audioPlayer.onAudioPositionChanged.listen((Duration d) {
        _playIndicator.value = d.inMilliseconds / (_duration?.inMilliseconds ?? 10000);
      });

      _status = _PlayStatus.playing;
    } catch (e) {
      error('_play error $e');
      et('录音播放出错');
      _status = _PlayStatus.pause;
    }

    safeSetState(() {});
  }

  /// 暂停播放
  Future<void> _pause() async {
    try {
      await _audioPlayer.pause();
      safeSetState(() => _status = _PlayStatus.pause);
    } catch (e) {
      error('_pause error $e');
    }
  }

  Future<void> _onTap() async {
    switch (_status) {
      case _PlayStatus.playing:
        _pause();
        break;
      case _PlayStatus.pause:
        _play();
        break;

      default:
    }
  }

  @override
  Widget build(BuildContext context) {
    return AppBtn(
      onTap: _onTap,
      width: sw - 40,
      height: 50,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[_buildLeading, _buildWave],
      ),
      padding: const EdgeInsets.symmetric(horizontal: 10),
      color: canvas(context),
      radius: 10,
    );
  }

  /// 头部图标
  Widget get _buildLeading {
    if (_status == _PlayStatus.pause) return Icon(Icons.play_arrow_rounded, color: theme(context));

    if (_status == _PlayStatus.playing) return Icon(Icons.pause_rounded, color: theme(context));

    return Icon(Icons.add_rounded, color: theme(context));
  }

  /// 构建波形图
  Widget get _buildWave {
    return Expanded(
      child: Stack(
        alignment: Alignment.center,
        children: <Widget>[
          _buildWaveBox(),
          ExValueBuilder<double>(
            child: _buildWaveBox(color: theme(context)),
            valueListenable: _playIndicator,
            builder: (_, double v, Widget? child) {
              return ClipPath(
                clipper: _IndicatorClipper(v),
                child: child,
              );
            },
          ),
        ],
      ),
    );
  }

  /// 构建一层着色波浪
  Widget _buildWaveBox({Color? color}) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: _recordWave
          .map(
            (double w) => Container(
              width: 4,
              height: w,
              margin: const EdgeInsets.only(right: 3),
              decoration: BoxDecoration(
                color: color ?? disable(context).withOpacity(0.2),
                borderRadius: BorderRadius.circular(2),
              ),
            ),
          )
          .toList(),
    );
  }
}

/// 波形图数据
const List<double> _recordWave = <double>[
  2,
  2,
  4,
  4,
  7,
  7,
  7,
  10,
  10,
  8,
  6,
  4,
  6,
  8,
  10,
  12,
  14,
  12,
  12,
  10,
  8,
  10,
  10,
  12,
  12,
  12,
  14,
  14,
  10,
  10,
  8,
  6,
  4,
  4,
  4,
  2,
];

class _IndicatorClipper extends CustomClipper<Path> {
  _IndicatorClipper(this.value);

  final double value;

  @override
  Path getClip(Size size) {
    return Path()..addRect(Rect.fromLTWH(0, 0, size.width * value, size.height));
  }

  @override
  bool shouldReclip(covariant _IndicatorClipper oldClipper) => oldClipper.value != value;
}
